#include "SharedMemory.h"

#include <QSystemSemaphore>
#include <QSharedMemory>


SharedMemory::SharedMemory(QString semaphore, QObject *parent) : QObject(parent) 
, m_valid(false)
, systemSemaphore(new QSystemSemaphore(QString(semaphore + "Semaphore"), 1))
, sharedMemory(new QSharedMemory(QString(semaphore)))
{
    // QSharedMemory("....")
    // 获取由该信号量守护的资源之一(如果有可用的)，并返回true。
    // 如果这个信号量守护的所有资源都已经被获取，调用就会阻塞，
    // 直到其中一个被具有相同键的信号量的另一个进程或线程释放为止。
    systemSemaphore->acquire();
    // 如果返回false，则发生系统错误。
    // 调用error()获得  QSystemSemaphore::SystemSemaphoreError 的值，
    // 该值指示发生了哪个错误。

    // QSystemSemaphore(const QString &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)
    // ~QSystemSemaphore()
    // bool	acquire()
    // QSystemSemaphore::SystemSemaphoreError	error() const
    // QString	errorString() const
    // QString	key() const
    // bool	release(int n = 1)
    // void	setKey(const QString &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)


    // 在linux / unix 中程序异常结束共享内存不会回收
    // 在这里需要提供释放内存的接口，就是在程序运行的时候如果有这段内存 先清除掉
    QSharedMemory nix_fix_shared_memory(semaphore);
    if (nix_fix_shared_memory.attach())
    {
        nix_fix_shared_memory.detach();
    }

    
    bool attached = false;
    // 试图将共享内存的副本附加到现有的段中。
    if ((attached = sharedMemory->attach())) {
        // 如果成功，则确定已经存在运行实例
        m_valid = false;
    } else {
        // 否则申请一字节内存
        sharedMemory->create(1);
        // 确定不存在运行实例
        m_valid = true;
    }
    systemSemaphore->release();

    // if (isRunning) {
    //     QMessageBox::waring(nullptr, tr("温馨提示"), tr("此程序已经被打开，无需重复运行"), tr("确定"));
    // }
}

bool SharedMemory::isValid() {
    return m_valid;
}